home *** CD-ROM | disk | FTP | other *** search
- ############################################################################
- #
- # Name: ximage.icn
- #
- # Title: Produces "executable" image of structured data
- #
- # Author: Robert J. Alexander
- #
- # Date: December 5, 1989
- #
- ############################################################################
- #
- # ximage() -- enhanced image()-type procedure that outputs all data
- # contained in structured types. It is called as follows:
- #
- # ximage(x)
- #
- # just like image(x) (the other arguments in the "procedure"
- # declaration are used for passing data among recursive levels). The
- # output has an "executable" appearance, which will look familiar to
- # any Icon programmer. The returned string for complex data contains
- # newline characters and indentation, suitable for write()-ing,
- # providing a pleasing and useful visual representation of the
- # structures.
- #
- ############################################################################
-
- procedure ximage(x,indent,done)
- local i,s,ss,state,t,xtag
- static tag,tr
- #
- # If this is the outer invocation, do some initialization.
- #
- if /(state := done) then {
- tr := &trace ; &trace := 0 # postpone tracing while in here
- indent := ""
- tag := 0
- done := table()
- }
- #
- # Determine the type and process accordingly.
- #
- indent := (if indent == "" then "\n" else "") || indent || " "
- ss := ""
- t := type(x)
- s := if xtag := \done[x] then xtag else case t of {
- #
- # Unstructured types just return their image().
- #
- "null" | "string" | "integer" | "real" | "cset" |
- "co-expression" | "file" | "procedure" | "external": image(x)
- #
- # List.
- #
- "list": {
- done[x] := xtag := "L" || (tag +:= 1)
- #
- # Figure out if there is a predominance of any object in the
- # list. If so, make it the default object.
- #
- t := table(0)
- every t[!x] +:= 1
- s := [,0]
- every t := !sort(t) do if s[2] < t[2] then s := t
- if s[2] > *x / 3 & s[2] > 2 then {
- s := s[1]
- t := ximage(s,indent || " ",done)
- if t ? (not any('\'"') & ss := tab(find(" :="))) then
- t := "{" || t || indent || " " || ss || "}"
- }
- else t := &null
- #
- # Output the non-defaulted elements of the list.
- #
- ss := ""
- every i := 1 to *x do if x[i] ~=== s then {
- ss ||:= indent || xtag || "[" || i || "] := " ||
- ximage(x[i],indent,done)
- }
- s := image(x)
- s[-1:-1] := "," || \t
- xtag || " := " || s || ss
- }
- #
- # Set.
- #
- "set": {
- done[x] := xtag := "S" || (tag +:= 1)
- every i := !sort(x) do {
- ss ||:= indent || "insert(" || xtag || "," ||
- ximage(i,indent,done,) || ")"
- }
- xtag || " := " || "set()" || ss
- }
- #
- # Table.
- #
- "table": {
- done[x] := xtag := "T" || (tag +:= 1)
- #
- # Output the table elements. This is a bit tricky, since
- # the subscripts might be structured, too.
- #
- every i := !sort(x) do {
- t := ximage(i[1],indent || " ",done)
- if t ? (not any('\'"') & s := tab(find(" :="))) then
- t := "{" || t || indent || " " || s || "}"
- ss ||:= indent || xtag || "[" ||
- t || "] := " ||
- ximage(i[2],indent,done)
- }
- #
- # Output the table, including its default value (which might
- # also be structured.
- #
- t := ximage(x[[]],indent || " ",done)
- if t ? (not any('\'"') & s := tab(find(" :="))) then
- t := "{" || t || indent || " " || s || "}"
- xtag || " := " || "table(" || t || ")" || ss
- }
- #
- # Record.
- #
- default: {
- done[x] := xtag := "R" || (tag +:= 1)
- every i := 1 to *x do {
- ss ||:= indent || xtag || "[" || i || "] := " ||
- ximage(\x[i],indent,done)
- }
- xtag || " := " || t || "()" || ss
- }
- }
- #
- # If this is the outer invocation, clean up before returning.
- #
- if /state then {
- &trace := tr # restore &trace
- }
- #
- # Return the result.
- #
- return s
- end
-